package com.cal.utms.action.dealing;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.cal.utms.dao.dealing.DealDao;
import com.cal.utms.dto.dealing.RevRepoDealDto;
import com.cal.utms.entity.Deal;
import com.cal.utms.entity.MoneyTransaction;
import com.cal.utms.model.dealing.RevRepoDealModel;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class RevRepoDealAction extends ActionSupport implements
ModelDriven<RevRepoDealDto> {

	private static final long serialVersionUID = 1L;
	RevRepoDealDto revRepoDealDto = new RevRepoDealDto();

	@Override
	public RevRepoDealDto getModel() {
		return revRepoDealDto;
	}
	
	public String queryRevRepo(){
		DealDao dealDao = new DealDao();
		if(revRepoDealDto.getQueryOne()!=null &&!revRepoDealDto.getQueryOne().equals("")){
			revRepoDealDto.setDeals(dealDao.queryDeals("RREPO", revRepoDealDto.getQueryOne()));
		}else{
			revRepoDealDto.setDeals(dealDao.queryDeals("RREPO"));
		}
		revRepoDealDto.setSuccess(true);
		return Action.SUCCESS;
	}
	
	public String queryDeal(){
		DealDao dealDao = new DealDao();
		RevRepoDealModel revRepoDealModel = new RevRepoDealModel();
		//dealDto.setDeal(dealDao.getById(dealDto.getId()));
		revRepoDealDto.setData(revRepoDealModel.mapRepoToDto(dealDao.getById(revRepoDealDto.getId())));
		revRepoDealDto.setSuccess(true);
		return Action.SUCCESS;
	}
	
	public String saveRevRepo(){
		RevRepoDealModel revRepoDealModel = new RevRepoDealModel();
		revRepoDealDto.setSuccess(true);
		
		Deal deal = revRepoDealModel.creatRevRepoDeal(revRepoDealDto);
		DealDao dealDao = new DealDao();
		if(deal.getRolloverShortmaturity()!=null && !deal.getRolloverShortmaturity().trim().equals("")){
			Deal prevDeal = dealDao.getByCode(deal.getRolloverShortmaturity());
			if(prevDeal==null){
				revRepoDealDto.setSuccess(false);
				revRepoDealDto.setStatus("Cannot Find Previous Deal");
				return Action.SUCCESS;
			}else if(deal.getFund().getId()!=prevDeal.getFund().getId()){
				revRepoDealDto.setSuccess(false);
				revRepoDealDto.setStatus("Funds Mismatch. RollOver Failed!");
				return Action.SUCCESS;
			}else if(deal.getValueDate().compareTo(prevDeal.getMaturityDate())<0){
				revRepoDealDto.setSuccess(false);
				revRepoDealDto.setStatus("Invalid Value Date. RollOver Failed!");
				return Action.SUCCESS;
			}else if(deal.getIssuer().getId()!=prevDeal.getIssuer().getId()){
				revRepoDealDto.setSuccess(false);
				revRepoDealDto.setStatus("Invalid Issuer. RollOver Failed!");
				return Action.SUCCESS;
			}else{
				prevDeal.setRolloverShortmaturity(deal.getDealCode());
				deal.setDeal(prevDeal);
			}
		}
		
		if(revRepoDealDto.isSuccess()){
			dealDao.addRevRepo(deal, revRepoDealDto);
		}		
		revRepoDealDto.setDealCode(deal.getDealCode());
		return Action.SUCCESS;
	}
	
	public String modifyRevRepo(){
		if(revRepoDealDto.getDealCode()==null){
			revRepoDealDto.setStatus("Empty Deal Code!");
			revRepoDealDto.setSuccess(false);
			return Action.SUCCESS;
		}
		DealDao dealDao = new DealDao();
		Deal deal = dealDao.getByCode(revRepoDealDto.getDealCode());
		if(deal==null){
			revRepoDealDto.setStatus("Invalid Deal Code!");
			revRepoDealDto.setSuccess(false);
			return Action.SUCCESS;
		}
		RevRepoDealModel revReDealModel = new RevRepoDealModel();
		revRepoDealDto.setSuccess(true);
		deal = revReDealModel.updateRevRepoDeal(deal, revRepoDealDto);
		if(revRepoDealDto.isSuccess()){
			dealDao.update(deal);
		}		
		return Action.SUCCESS;
	}
	
	public String rejectRevRepoDeal(){
		System.out.println("Reject req"+ revRepoDealDto.getDealCode());
		if(revRepoDealDto.getDealCode()==null){
			revRepoDealDto.setStatus("Empty Deal Code!");
			revRepoDealDto.setSuccess(false);
			return Action.SUCCESS;
		}
		DealDao dealDao = new DealDao();
		Deal deal = dealDao.getByCode(revRepoDealDto.getDealCode());
		if(deal==null){
			revRepoDealDto.setStatus("Invalid Deal Code!");
			revRepoDealDto.setSuccess(false);
			return Action.SUCCESS;
		}
		deal.setModifiedDate(new Date());
		deal.setModifiedUser(revRepoDealDto.getUser());
		deal.setStatus("Rejected");
		dealDao.update(deal);
		revRepoDealDto.setSuccess(true);
		return Action.SUCCESS;
	}
	
	public String confirmRevRepo(){		
		DealDao dealDao = new DealDao();
		revRepoDealDto.setSuccess(true);
		
		if(revRepoDealDto.getDealCode()==null){
			revRepoDealDto.setSuccess(false);
			revRepoDealDto.setStatus("Cannot Find Deal Code!");	
		}	
		Deal oldDeal = dealDao.getByCode(revRepoDealDto.getDealCode());

		if(oldDeal.getCreatedUser().equals(revRepoDealDto.getUser())){
			revRepoDealDto.setSuccess(false);
			revRepoDealDto.setStatus("Created User cannot confirm!");
			return Action.SUCCESS;
		}

		RevRepoDealModel revRepoDealModel = new RevRepoDealModel();
		Deal deal = revRepoDealModel.confRevRepoDeal(revRepoDealDto);
		if(oldDeal.equals(deal)){
			
			List<MoneyTransaction> moneyTransactions = new ArrayList<MoneyTransaction>();			
			Date today = new Date();
			MoneyTransaction creditEntry = new MoneyTransaction();
			MoneyTransaction debitEntry = new MoneyTransaction();
			
			creditEntry.setCreditDebit("C");
			if(deal.getIssuer()!=null){
				creditEntry.setCustomerType("ISU");
				creditEntry.setTranTo(deal.getIssuer().getId());
			}else{
				revRepoDealDto.setStatus("Cannot Find Issuer for Money Transactions!");
				revRepoDealDto.setSuccess(false);
				return Action.SUCCESS;
			}			
			creditEntry.setDate(today);
			creditEntry.setEffectDate(deal.getValueDate());
			creditEntry.setFund(deal.getFund());
			creditEntry.setTranAmont(deal.getDealValue());
			creditEntry.setTranType("DEAL");
			creditEntry.setTranTypeId(deal.getId());
			//TODO creditEntry.setUser();
			
			debitEntry.setCreditDebit("D");
			if(deal.getFund()!=null){
				debitEntry.setCustomerType("FUN");
				debitEntry.setTranTo(deal.getFund().getId());
			}else{
				revRepoDealDto.setStatus("Cannot Find Fund for Money Transactions!");
				revRepoDealDto.setSuccess(false);
				return Action.SUCCESS;
			}			
			debitEntry.setDate(today);
			debitEntry.setEffectDate(deal.getValueDate());
			debitEntry.setFund(deal.getFund());
			debitEntry.setTranAmont(deal.getDealValue().multiply(new BigDecimal(-1)));
			debitEntry.setTranType("DEAL");
			debitEntry.setTranTypeId(deal.getId());
			//TODO creditEntry.setUser();
			
			moneyTransactions.add(creditEntry);
			moneyTransactions.add(debitEntry);
			
			if(deal.getWithholdingTax().equals("Upfront")){
				creditEntry = new MoneyTransaction();
				debitEntry = new MoneyTransaction();
				creditEntry.setCreditDebit("C");
				if(deal.getFund().getCustodian()!=null){
					creditEntry.setCustomerType("CTO");
					creditEntry.setTranTo(deal.getFund().getCustodian().getId());
				}else{
					revRepoDealDto.setStatus("Cannot Find Custodian for Money Transactions!");
					revRepoDealDto.setSuccess(false);
					return Action.SUCCESS;
				}			
				creditEntry.setDate(today);
				creditEntry.setEffectDate(deal.getValueDate());
				creditEntry.setFund(deal.getFund());
				if(deal.getWithholdingTaxRate()==null){
					revRepoDealDto.setStatus("Cannot Find WHT Rate for Money Transactions!");
					revRepoDealDto.setSuccess(false);
					return Action.SUCCESS;
				}
				creditEntry.setTranAmont(deal.getDealValue().multiply(deal.getWithholdingTaxRate()));
				creditEntry.setTranType("WHT");
				creditEntry.setTranTypeId(deal.getId());
				//TODO creditEntry.setUser();
				
				debitEntry.setCreditDebit("D");
				if(deal.getFund()!=null){
					debitEntry.setCustomerType("FUN");
					debitEntry.setTranTo(deal.getFund().getId());
				}else{
					revRepoDealDto.setStatus("Cannot Find Fund for Money Transactions!");
					revRepoDealDto.setSuccess(false);
					return Action.SUCCESS;
				}			
				debitEntry.setDate(today);
				debitEntry.setEffectDate(deal.getValueDate());
				debitEntry.setFund(deal.getFund());
				debitEntry.setTranAmont(deal.getDealValue().multiply(deal.getWithholdingTaxRate()).multiply(new BigDecimal(-1)));
				debitEntry.setTranType("WHT");
				debitEntry.setTranTypeId(deal.getId());
				//TODO creditEntry.setUser();
				
				moneyTransactions.add(creditEntry);
				moneyTransactions.add(debitEntry);
			}			
			
			dealDao.confirm(deal, moneyTransactions);
			revRepoDealDto.setStatus("OK");
			revRepoDealDto.setSuccess(true);
		}else{
			revRepoDealDto.setStatus("Deal Mismatch!");
			revRepoDealDto.setSuccess(false);			
		}
		
		return Action.SUCCESS;
	}
	
	public String valuateDeal(){
		RevRepoDealModel revRepoDealModel = new RevRepoDealModel();
		revRepoDealDto.setSuccess(true);
		revRepoDealModel.valuate(revRepoDealDto);
		return Action.SUCCESS;
	}

}
